package com.atguigu.spzx.manager.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.atguigu.spzx.manager.mapper.ProductDetailsMapper;
import com.atguigu.spzx.manager.mapper.ProductMapper;
import com.atguigu.spzx.manager.mapper.ProductSkuMapper;
import com.atguigu.spzx.manager.service.ProductService;
import com.atguigu.spzx.model.dto.product.ProductDto;
import com.atguigu.spzx.model.dto.product.ProductSaveDto;
import com.atguigu.spzx.model.entity.product.Product;
import com.atguigu.spzx.model.entity.product.ProductDetails;
import com.atguigu.spzx.model.entity.product.ProductSku;
import com.atguigu.spzx.model.vo.product.ProductVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class ProductServiceImpl implements ProductService {
    @Resource
    ProductMapper productMapper;
    @Resource
    ProductDetailsMapper productDetailsMapper;
    @Resource
    ProductSkuMapper productSkuMapper;
    @Override
    public PageInfo<ProductVo> page(Integer pageNum, Integer pageSize, ProductDto productDto) {
        PageHelper.startPage(pageNum,pageSize);

        List<ProductVo> productVoList = productMapper.findByCondition(productDto);

        return new PageInfo<>(productVoList);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(ProductSaveDto productSaveDto) {
        //1、保存product数据
        Product product = new Product();
        //BeanUtils.copyProperties 可以将一个对象的相同名称类型的属性值拷贝给另一个对象
        BeanUtils.copyProperties(productSaveDto , product);
        productMapper.save(product);
        Long productId = product.getId();
        //2、保存product_details: 需要绑定productId   1个spu只有一条详情图记录
        ProductDetails productDetails = new ProductDetails();
        productDetails.setId(productId);
        productDetails.setProductId(productId);
        productDetails.setImageUrls(productSaveDto.getDetailsImageUrls());
        productDetailsMapper.save(productDetails);
        //3、批量保存product_sku: 需要绑定productId
        List<ProductSku> productSkuList = productSaveDto.getProductSkuList();
        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
        //给集合中的每个sku绑定productId
        productSkuList.forEach(productSku -> {
            productSku.setProductId(productId);
            //每个sku对应唯一的一个skuCode编码：和id作用类似 表示唯一的sku，但是一般是给用户使用的
            // UUID不唯一 但是过长、过滤性差 无序  手动生成id或者唯一编码时 可以使用带时间戳的方式生成
            //雪花算法： 时间戳+机器码+毫秒内的序号  id长度只有19位，按照时间递增，十进制便于比较
            productSku.setSkuCode(snowflake.nextIdStr());
            productSku.setSkuName(product.getName()+" "+ productSku.getSkuSpec());
            productSku.setSaleNum(0);
            productSku.setStatus(0);

        });
        productSkuMapper.batchSave(productSkuList);

    }

    @Override
    public ProductSaveDto getById(Long id) {
        //异步编排：使用三个子线程查询 三个子线程都结束后组装数据返回
        //1、查询product详情数据
        //2、查询product_details
        //3、查询product_sku集合


        //自定义sql+自定义映射解析
        ProductSaveDto productSaveDto = productMapper.getProductSaveDtoById(id);
        return productSaveDto;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateById(ProductSaveDto productSaveDto) {
        //更新product
        Product product = new Product();
        BeanUtils.copyProperties(productSaveDto , product);
        productMapper.updateById(product);
        //更新productDetails
        ProductDetails productDetails = new ProductDetails();
        productDetails.setId(product.getId());
        productDetails.setImageUrls(productSaveDto.getDetailsImageUrls());
        productDetailsMapper.updateById(productDetails);

        List<ProductSku> skuList = productSaveDto.getProductSkuList();
        //更新productSku
        skuList.forEach(productSku -> {
            productSku.setSkuName(product.getName()+" "+ productSku.getSkuSpec());

            productSkuMapper.updateById(productSku);
        });



    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(Long id) {
        productMapper.deleteById(id);
        productDetailsMapper.deleteById(id);
        productSkuMapper.deleteByProductId(id);
    }

    @Override
    public void updateAuditStatus(Long id, Integer auditStatus) {
        productMapper.updateAuditStatus(id , auditStatus);
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        productMapper.updateStatus(id , status);
        productSkuMapper.updateStatus(id , status);
    }
}
